
/**
 * Content: Lambda表达式语法、Lambda表达式用途
 * --------------------------------------------------
 * Lambda 表达式入门，看这篇就够了: https://blog.csdn.net/qing_gee/article/details/104231239
 */

public class java_0700_Lambda {

    public static void main(String[] args) {

        // Lambda表达式语法
        System.out.println("--------------------Lambda表达式语法--------------------");
        /**
         * 1.参数类型可以省略
         * 2.假如只有一个参数，()括号可以省略
         * 3.如果方法体只有一条语句, {}大括号可以省略
         * 4.如果方法体中唯一的语句是 return 返回语句，那省略大括号的同时 return 也要省略
         */

        // 无参数-无返回值 ———— 这其实是 重写接口 中的方法
        //                    相当于: 创建一个实现了 If1 接口的 匿名类, 实现了 If1 声明的方法, 然后通过多态赋值给 If1 接口
        If1 if1 = () -> {
            System.out.println("无参数-无返回值");
        };
        if1.test();

        // 两个参数-有返回值
//        If2 if2 = (String name, int age) -> {
        If2 if2 = (name, age) -> {
            System.out.println("两个参数-有返回值: name: " + name + "-age: " + age);
            return age;
        };
        int res = if2.test("谢清照", 18);

        // Lambda方法引用
        System.out.println("--------------------Lambda方法引用--------------------");

        // 这段代码, 内有乾坤 ———— 这其实是 重写接口 中的方法
        //                       相当于: 创建一个实现了 If2 接口的 匿名类, 用 LambdaFunc::testA 代替实现 If1 声明的方法
        //                       注意: LambdaFunc::testA 与 If1 内部的方法 参数和返回值 类型必须一致
        //                              (且只要 参数和返回值 相同, LambdaFunc::testA 可以用来实现 任意接口)
        If2 ifB = LambdaFunc::testA;
        int res2 = if2.test("谢清照", 18);

        // Lambda表达式用途
        System.out.println("--------------------Lambda表达式用途--------------------");
        /**
         * Lambda 表达式可以做的事情:
         *      (1).为变量赋值 (一般用于创建 接口类型):   Runnable r = () -> System.out.println("沉默王二");
         *      (2).作为普通方法或者构造方法的参数:       new Thread(() -> System.out.println("沉默王二")).start();
         *      (3).作为 return 结果:                  return (pathname) -> pathname.toString().endsWith(ext);
         */
        /**
         * 不要在 Lambda 表达式主体内对方法内的局部变量进行修改，否则编译也不会通过：Lambda 表达式中使用的变量必须是 final 的。
         */

        // 创建匿名线程1 - Lambda 表达还是创建
        new Thread(() -> System.out.println("中国建筑科学研究院！")).start();

        // 创建匿名线程2 - Lambda 表达还是创建
        Runnable r = () -> { System.out.println("中国建筑科学研究院！"); };
        Runnable r2 = () -> System.out.println("中国建筑科学研究院！");
        // 用 LambdaFunc2 中的 testB() 方法代替 Runnable 接口中需要实现的 run() 函数
        Runnable r3 = LambdaFunc2::testB;
        r.run();


    }

    // 可以看到, 接口中只有 1 个方法声明
    interface If1 {
        // 无参数-无返回值
        void test();
    }

    interface If2 {
        // 两个参数-有返回值
        int test(String name, int age);
    }

}

class LambdaFunc {
    static int testA(String name, int age) {
        System.out.println("两个参数-有返回值: name: " + name + "-age: " + age);
        return age;
    }
}

class LambdaFunc2 {
    static void testB() {
        System.out.println("中国建筑科学研究院！");
    }
}